package com.hardydou.lang;

import java.util.Date;
import java.util.concurrent.*;

/**
 * @author ：hardy
 * @description：延迟队列示例
 * @date ：Created in 2021/1/18
 * @Copyright ：Hardydou.com
 */
public class DelayQueueCase {

    private DelayQueue<DelayTask> taskQueue = new DelayQueue<>();

    public void putTask(String name, long duration) {
        putTask(name, new Date(System.currentTimeMillis() + duration));
    }

    public void putTask(String name, Date time) {
        putTask(new DelayTask(name, time));
    }

    public void putTask(DelayTask delayTask) {
        taskQueue.put(delayTask);
    }

    public Consumer newConsumer() {
        return new Consumer();
    }

    class DelayTask implements Delayed, Runnable {

        private String name;
        private Date time;

        public DelayTask(String name, Date time) {
            this.name = name;
            this.time = time;
        }

        @Override
        public long getDelay(TimeUnit unit) {
            return unit.convert((time.getTime() - System.currentTimeMillis()), TimeUnit.MILLISECONDS);
        }

        @Override
        public int compareTo(Delayed o) {
            long s = this.getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS);
            return (int) s;
        }

        @Override
        public void run() {
            System.out.println("Run " + this.toString());
        }

        @Override
        public String toString() {
            return "DelayTask{" +
                    "name='" + name + '\'' +
                    ", time=" + time.getTime() +
                    ", now=" + System.currentTimeMillis() +
                    '}';
        }
    }


    class Consumer extends Thread {
        @Override
        public void run() {
            try {
                System.out.println("start Consumer ");
                DelayTask task;
                while (null != (task = taskQueue.take())) {
                    task.run();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
